package com.skydroid.skydroidfpvdemo;

import android.Manifest;
import android.hardware.usb.UsbDevice;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import com.skydroid.fpvlibrary.uartvideo.FpvRenderer;
import com.skydroid.fpvlibrary.uartvideo.GLHttpVideoSurface;
import com.skydroid.fpvlibrary.uartvideo.VideoClient;
import com.skydroid.fpvlibrary.uartvideo.usb.DeviceFilter;
import com.skydroid.fpvlibrary.uartvideo.usb.USBMonitor;

import java.util.List;

public class MainActivity extends AppCompatActivity {
    /**
     * 1.设置亮度/对比度/色调/饱和度
     *  VideoClient.setCSC(int brightness, int contrast, int hue, int saturation)
     *  2.设置曝光
     *  VideoClient.setExposureTime(int time, boolean auto)
     *  3.云台控制
     *  VideoClient.setTripodDirection(VideoClient.Direction direction)
     *  4.设置云台分辨率
     *  VideoClient.setVideoSize(VideoClient.Sizes size)
     *  5.云台翻转
     *  VideoClient.flip()
     *  6.云台校准
     *  VideoClient.calibrateTripod()
     *  7.设置云台角度 一键向前、向上、向下   angle 角度 取值
     *      180 云台旋转垂直向上
     *      90 云台旋转水平向前
     *      0 云台旋转垂直向下
     *  VideoClient.setTripodAngle(int angle)
     *  8.设置 LED
     *  VideoClient.toggleLed()
     *  9.切换摄像头
     *  VideoClient.switchCamera()
     *  10.发送数传数据
     *  VideoClient.sendData(byte[] bytes)
     *  11.发送图传数据
     *  VideoClient.sendVideo(byte[] bytes)
     *  12.设置 数据回调
     *  VideoClient.setClientListener(ClientListener listener)
     *
     *  13 FpvRenderer 为 SDK 自带的解码功能
     *
     */
    private VideoClient video;

    private USBMonitor mUSBMonitor;

    private UsbDevice uartDevice;

    private GLHttpVideoSurface mPreviewDualVideoView;

    private Handler mainHandler = new Handler(Looper.getMainLooper());

    private FpvRenderer fpvRenderer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        requestPermissions();
        //视频view
        initVideo();

        video = new VideoClient(this);
        video.setClientListener(new VideoClient.ClientListener(){

            @Override
            public void onH264Received(byte[] bytes) {
                if(fpvRenderer != null){
                    fpvRenderer.decodeH264(bytes,bytes.length);
                }
            }

            @Override
            public void onGPSReceived(byte[] bytes) {

            }

            @Override
            public void onDataReceived(byte[] bytes) {
                Log.e("onDataReceived",new String(bytes));
            }

            @Override
            public void onDebugReceived(byte[] bytes) {

            }

            @Override
            public void onError(String s) {

            }
        });

        mUSBMonitor = new USBMonitor(this, mOnDeviceConnectListener);
        final List<DeviceFilter> filters = DeviceFilter.getDeviceFilters(this, R.xml.device_filter);
        mUSBMonitor.setDeviceFilter(filters);
        mUSBMonitor.register();

        findViewById(R.id.tv_test).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                video.setTripodAngle(0);
            }
        });

    }

    private void requestPermissions() {
        ActivityCompat.requestPermissions(
                this, new String[]{
                        Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE
                }, 0
        );
    }

    private void initVideo(){
        mPreviewDualVideoView = findViewById(R.id.video);
        mPreviewDualVideoView.init();

        fpvRenderer = new FpvRenderer();
        fpvRenderer.setGlHttpVideoSurface(mPreviewDualVideoView);
    }

    //使用 USBMonitor 处理USB连接回调
    private final USBMonitor.OnDeviceConnectListener mOnDeviceConnectListener = new USBMonitor.OnDeviceConnectListener() {
        // USB device attach
        // USB设备插入
        @Override
        public void onAttach(final UsbDevice device) {

            if(deviceHasConnected(device) || uartDevice != null)
                return;

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (device == null) {
                            final List<UsbDevice> devices = mUSBMonitor.getDeviceList();
                            if (devices.size() == 1) {
                                mUSBMonitor.requestPermission(devices.get(0));
                            }
                        } else {
                            mUSBMonitor.requestPermission(device);
                        }
                    } catch (Exception e){
                        e.printStackTrace();
                    }
                }
            });
        }

        // USB device detach
        // USB设备物理断开
        @Override
        public void onDettach(UsbDevice device) {
            if(!deviceIsUartVideoDevice(device)) {
                return;
            }

            if(!deviceHasConnected(device)) {
                return;
            }

            disconnected();
        }

        // USB device has obtained permission
        // USB设备获得权限
        @Override
        public void onConnect(UsbDevice device, USBMonitor.UsbControlBlock ctrlBlock, boolean createNew) {
            if(!deviceIsUartVideoDevice(device)) {
                return;
            }
            if(deviceHasConnected(device)) {
                return;
            }

            synchronized (this) {
                if(deviceIsUartVideoDevice(device)) {
                    //打开
                    if(video.openUsbSerial(device)){
                        uartDevice = device;
                    }

                }
            }
        }
        // USB device disconnected
        // USB设备关闭连接
        @Override
        public void onDisconnect(UsbDevice device, USBMonitor.UsbControlBlock ctrlBlock) {
            if(!deviceIsUartVideoDevice(device)) {
                return;
            }

            if(!deviceHasConnected(device)) {
                return;
            }

            disconnected();
        }
        // USB device obtained permission failed
        // USB设备权限获取失败
        @Override
        public void onCancel() {

        }
    };

    private boolean deviceHasConnected(UsbDevice device) {
        return device != null && device.equals(uartDevice);
    }

    private static boolean deviceIsUartVideoDevice(UsbDevice device) {
        return device != null && (device.getVendorId() == 4292 && device.getProductId() == 60000);
    }

    private synchronized void disconnected() {
        video.close();
        fpvRenderer.stopPlayback();
        uartDevice = null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        disconnected();

        if (mUSBMonitor != null) {
            mUSBMonitor.unregister();
            mUSBMonitor.destroy();
            mUSBMonitor = null;
        }
    }
}
